﻿using UnityEngine;
using System.Collections;
using System;
using System.Runtime.InteropServices;
using System.IO;
using SuSPExtension;
using B83.Win32;

/// <summary>
/// 一共可选择三种样式
/// </summary>
public enum enumWinStyle
{
    /// <summary>
    /// 置顶
    /// </summary>
    WinTop,
    /// <summary>
    /// 置顶并且透明
    /// </summary>
    WinTopApha,
    /// <summary>
    /// 置顶透明并且可以穿透
    /// </summary>
    WinTopAphaPenetrate
}
public class WinSetting : MonoSingleton<WinSetting>
{

    #region Win函数常量
    private struct MARGINS
    {
        public int cxLeftWidth;
        public int cxRightWidth;
        public int cyTopHeight;
        public int cyBottomHeight;
    }

    [DllImport("user32.dll")]
    static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
    [DllImport("user32.dll")]
    static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);

    [DllImport("user32.dll")]
    static extern int GetWindowLong(IntPtr hWnd, int nIndex);

    [DllImport("user32.dll")]
    static extern int SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int X, int Y, int cx, int cy, int uFlags);

    [DllImport("user32.dll")]
    static extern int SetLayeredWindowAttributes(IntPtr hwnd, int crKey, int bAlpha, int dwFlags);

    [DllImport("Dwmapi.dll")]
    static extern uint DwmExtendFrameIntoClientArea(IntPtr hWnd, ref MARGINS margins);
    [DllImport("user32.dll")]
    private static extern int SetWindowLong(IntPtr hWnd, int nIndex, uint dwNewLong);
    private const int WS_POPUP = 0x800000;
    private const int GWL_EXSTYLE = -20;
    private const int GWL_STYLE = -16;
    private const int WS_EX_LAYERED = 0x00080000;
    private const int WS_BORDER = 0x00800000;
    private const int WS_CAPTION = 0x00C00000;
    private const int SWP_SHOWWINDOW = 0x0040;
    private const int LWA_COLORKEY = 0x00000001;
    private const int LWA_ALPHA = 0x00000002;
    private const int WS_EX_TRANSPARENT = 0x20;
    //
    private const int ULW_COLORKEY = 0x00000001;
    private const int ULW_ALPHA = 0x00000002;
    private const int ULW_OPAQUE = 0x00000004;
    private const int ULW_EX_NORESIZE = 0x00000008;
    #endregion

    private uint threadId = WinAPI.GetCurrentThreadId();
    private enumWinStyle WinStyle = enumWinStyle.WinTop;//窗体样式

    private int windowBeginState;
    private IntPtr hwnd;
    private SystemWindow syswin;

    bool isTransparent = false;//是否透明
    bool isAphaPenetrate = false;//是否要穿透窗体
    float hoverAlpha = 0.5f;//划过时的透明度乘数

    public int WinAlpha
    {
        set{
            AppMgr.Instance.appConfig.alpha = value;
            syswin.Alpha = (byte)value;
        }
    }

    public bool IsPenetrate
    {
        get
        {
            return isAphaPenetrate;
        }
        set
        {
            isAphaPenetrate = value;
            if (value)
            {
                WindowPenetrate();
            }
            else
            {
                WindowPenetrateRestore();
            }
        }
    }

    protected override void Init()
    {
        base.Init();

        EventBus.Instance.AddEventHandler(EventID.OnHoverSpineObject, OnHoverSpineObject);

        AppConfig config = AppMgr.Instance.appConfig;

        uint threadId = WinAPI.GetCurrentThreadId();
        hwnd = GetMainWindow(threadId, "UnityWndClass");
        syswin = new SystemWindow(hwnd.ToString());
        syswin.Alpha = (byte)config.alpha;
        if (Application.platform == RuntimePlatform.WindowsPlayer)
        {
            WindowPenetrate();
        }
    }

    public static IntPtr GetMainWindow(uint aThreadId, string aClassName = null)
    {
        IntPtr win = IntPtr.Zero;
        Window.EnumThreadWindows(aThreadId, (W, _) =>
        {
            if (Window.IsWindowVisible(W) && (win == null || (aClassName != null && Window.GetClassName(W) == aClassName)))
                win = W;
            return true;
        }, IntPtr.Zero);
        return win;
    }

    private void WindowPenetrateRestore()
    {
        syswin.TopMost = false;
        syswin.MakePenetrateRestore();
    }

    private void WindowPenetrate()
    {
        syswin.TopMost = true;
        syswin.MakePenetrate();
        syswin.MakeWindowNoBorder();
        syswin.Maximize();
        syswin.MakeBackgroundTransparent();
    }

    private void OnHoverSpineObject()
    {
        syswin.Alpha = (byte)(int)(AppMgr.Instance.appConfig.alpha * hoverAlpha);
    }
}